package com.zhou.project.configurations.shiro.realm;

import com.zhou.project.moduels.user.entity.User;
import com.zhou.project.moduels.user.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;

/**
 * @author zhouhonggang
 * @version 1.0.0
 * @project spring-boot-project
 * @datetime 2022-03-08 15:59
 * @description: TODO
 */
public class CustomRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    //设置用于匹配密码的CredentialsMatcher
    {
        HashedCredentialsMatcher hashMatcher = new HashedCredentialsMatcher();
        hashMatcher.setHashAlgorithmName(Sha256Hash.ALGORITHM_NAME);
        hashMatcher.setStoredCredentialsHexEncoded(false);
        hashMatcher.setHashIterations(1024);
        this.setCredentialsMatcher(hashMatcher);
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        User entity = (User) getAvailablePrincipal(principalCollection);

        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.setRoles(entity.getRoles());
        simpleAuthorizationInfo.setStringPermissions(entity.getPerms());
        return simpleAuthorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken)authenticationToken;
        String username = usernamePasswordToken.getUsername();
        //模拟查询用户对象
        User entity = userService.findUserByName(username);
        if (ObjectUtils.isEmpty(entity)) {
            throw new UnknownAccountException("No account found for admin [" + username + "]");
        }
        //模拟查询用户角色集合
        entity.setRoles(userService.getRolesByUser(username));
        //模拟查询用户权限集合
        entity.setPerms(userService.getPermsByUser(username));

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(entity, entity.getPass(), getName());
        if (entity.getSalt() != null) {
            info.setCredentialsSalt(ByteSource.Util.bytes(entity.getSalt()));
        }
        return info;
    }

}
